package cn.com.bonc.khjy.schedu;


import cn.com.bonc.khjy.bean.RestFullBean;
import cn.com.bonc.khjy.utils.JacksonMapper;
import cn.com.bonc.khjy.utils.PrintUtil;
import cn.com.bonc.khjy.utils.SystemMessageId;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;


/**
 * Created by hanbing on 2019/6/02.
 */
@Component
public class RestFullMonitor {
    private final static Log logger = LogFactory.get();
    @Autowired
    private RestTemplate restTemplate;
    private List<RestFullBean> restRuleList;
    //是否启动线程控制变量
    private volatile boolean restFlag = false;
    public List<RestFullBean> getRestRuleList() {
        return restRuleList;
    }

    public void setRestRuleList(List<RestFullBean> restRuleList) {
        this.restRuleList = restRuleList;
    }
    //消息队列-缓存变量
    private Map<String,LinkedBlockingQueue< String >> workOrderRSInfo;

    public Map<String, LinkedBlockingQueue<String>> getWorkOrderRSInfo() {
        return workOrderRSInfo;
    }

    public void setWorkOrderRSInfo(Map<String, LinkedBlockingQueue<String>> workOrderRSInfo) {
        this.workOrderRSInfo = workOrderRSInfo;
    }

    @PostConstruct
    public void init() {
        logger.debug("RestFull传输加载规则：{}", "ContactSource.json");
        List<RestFullBean> restRuleTemp=new ArrayList<>();
        Map<String,LinkedBlockingQueue<String>> workOrderInfoValue=new HashMap<>();
        try {

            InputStream in = new DefaultResourceLoader().getResource("classpath:ContactSource.json").getInputStream();
            String jsonData = IOUtils.toString(in, "UTF-8");
            Map< String, ? > map = JacksonMapper.INSTANCE.readJsonToObject( jsonData );
            String ruleStr=JacksonMapper.INSTANCE.writeObjectToJson(map.get("restList"));
            List< Map > ruleList= JacksonMapper.INSTANCE.readJsonToList(ruleStr);
            for(int i=0;i<ruleList.size();i++){
                Map rule=ruleList.get(i);
                Iterator<Map.Entry<String, Map>> iterator = rule.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, Map> entry = iterator.next();
                    String id=entry.getKey();
                    Map parameter=entry.getValue();
                    RestFullBean rfb=new RestFullBean(id,String.valueOf(parameter.get("url")),String.valueOf(parameter.get("topic")));
                    String headerParameter=JacksonMapper.INSTANCE.writeObjectToJson(parameter.get("headerParameter"));
                    String fixedParameter=JacksonMapper.INSTANCE.writeObjectToJson(parameter.get("fixedParameter"));
                    String bodyParameter=JacksonMapper.INSTANCE.writeObjectToJson(parameter.get("bodyParameter"));
                    rfb.setHeaderParameter(PrintUtil.isNotBlank(headerParameter)?JacksonMapper.INSTANCE.readJsonToList(headerParameter):null);
                    rfb.setFixedParameter(PrintUtil.isNotBlank(fixedParameter)?JacksonMapper.INSTANCE.readJsonToList(fixedParameter):null);
                    rfb.setBodyParameter(PrintUtil.isNotBlank(bodyParameter)?JacksonMapper.INSTANCE.readJsonToList(bodyParameter):null);
                    restRuleTemp.add(rfb);
                    workOrderInfoValue.put(id,new LinkedBlockingQueue<>( 1000 ));
                    logger.debug("RestFull传输加载规则:{}",rfb);
                }

            }
            this.setRestRuleList(restRuleTemp);
            this.setWorkOrderRSInfo(workOrderInfoValue);
        } catch (IOException e) {
            logger.error("RestFullMonitor-init-IOException",e);
        } catch (Exception e) {
            logger.error("RestFullMonitor-init-Exception",e);
        }
    }
    public void toThreadStart() {

            ThreadUtil.execAsync( () -> {
                while ( !restFlag ) {
                    List<RestFullBean> ls=this.getRestRuleList();
                    Map<String, LinkedBlockingQueue< String >> queueMap= this.getWorkOrderRSInfo();
                    Iterator<Map.Entry<String, LinkedBlockingQueue< String >>> iterator = queueMap.entrySet().iterator();
                    while (iterator.hasNext()) {
                        Map.Entry<String, LinkedBlockingQueue< String >> entry = iterator.next();
                        String id=entry.getKey();
                        LinkedBlockingQueue<String> queue=entry.getValue();
                        for (RestFullBean restFullBean:
                                ls) {
                                try {
                                    String  input = queue.take();
                                    logger.debug("toThreadStart-line>>>,{}",input);
                                    if(PrintUtil.isNotBlank(input)){
                                        Map<String, ?> map = JacksonMapper.INSTANCE.readJsonToObject(input);
                                        String cid = String.valueOf(map.get("id"));
                                        if(id.equals(restFullBean.getId()) &&id.equals(cid)){

                                            sendWXData(input,restFullBean);
                                        }
                                    }
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }



                        }
                    }


                }});

    }
    public void toThreadStop() {
          restFlag= true;

    }
    private void sendWXData( String data ,RestFullBean restFullBean) {
        try {
            //String encodeTypeParam = URLEncoder.encode( URLEncoder.encode( "dsjmb", "utf-8" ), "utf-8" );
           // String url = restFullBean.getUrl()+"?access_token=123456&type=" + encodeTypeParam;
            String url = restFullBean.getUrl()+"?";
            StringBuilder stringBuilder=new StringBuilder(url);
            List<Map> fixPar=restFullBean.getFixedParameter();
            for(int i=0;i<fixPar.size();i++){
                Map tmp=fixPar.get(i);
                String encode=String.valueOf(tmp.get("encode"));
                stringBuilder.append(String.valueOf(tmp.get("key")));
                stringBuilder.append("&");
                stringBuilder.append("true".equals(encode)? URLEncoder.encode( URLEncoder.encode( String.valueOf(tmp.get("value")), "utf-8" ), "utf-8" ):String.valueOf(tmp.get("value")));
            }
            url=stringBuilder.toString();
            logger.debug("url>>>>",url);
            MultiValueMap< String, String > map = new LinkedMultiValueMap<>();
            Map< String, ? > inputMap = JacksonMapper.INSTANCE.readJsonToObject( data );
            inputMap.remove("id");
            Iterator<? extends Map.Entry<String, ?>> iterator = inputMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, ?> entry = iterator.next();
                String key=entry.getKey();

                map.add( key,  JacksonMapper.INSTANCE.writeObjectToJson(entry.getValue()) );
            }

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType( MediaType.APPLICATION_FORM_URLENCODED );
            HttpEntity< MultiValueMap< String, String > > requestEntity = new HttpEntity<>( map, headers );
            ResponseEntity< String > response = restTemplate.postForEntity( url, requestEntity, String.class );
            logger.debug("已发送消息状态:{},{}",response.getStatusCode(),data);
        } catch ( UnsupportedEncodingException e ) {
            logger.error( SystemMessageId.CMP0971, e.getMessage() );
        }
    }

    public void addQueueLine(String str){
        if ( StrUtil.isNotBlank( str ) ) {
            Map<String, ?> map = JacksonMapper.INSTANCE.readJsonToObject(str);
            String id = String.valueOf(map.get("id"));
            LinkedBlockingQueue queue = this.getWorkOrderRSInfo().get(id);
            try {
                queue.put(str);
                logger.debug("消息队列：{}", queue);
            } catch (InterruptedException e) {
                logger.error(e, SystemMessageId.CMP0705, Thread.currentThread().getName());
            }
        }
    }

}
